package fr.mywiki.business.entry.meta.datatype.number;

import java.text.ParseException;
import java.util.Locale;

import org.jdom.Attribute;
import org.jdom.Element;

import fr.mywiki.business.entry.meta.DataType;
import fr.mywiki.business.resources.ResourceManager;

public class RealNumber implements DataType{
  public static final String TYPE_NAME = "realNumber";
  
  public static final String TYPE_BUNDLE_KEY = "model.type.realNumber.display";
  public static final String TYPE_BUNDLE_KEY_MORE = "model.type.realNumber.display.morethan";
  public static final String TYPE_BUNDLE_KEY_LESS = "model.type.realNumber.display.lessthan";
  public static final String TYPE_BUNDLE_KEY_BETWEEN = "model.type.realNumber.display.between";
  
  /* The errors */
  public static final String INVALID_TYPE = "model.validation.realnumber.badtype";
  public static final String INVALID_NUMBER_MIN = "model.validation.realnumber.lessmin";
  public static final String INVALID_NUMBER_MAX = "model.validation.realnumber.morethan";

  /* Xml attributes names */
  public static final String MIN_VAL = "min";
  public static final String MAX_VAL = "max";
  
	/**
	 * The upper limit of the value a number in that property can have. If null, no upper limit.
	 */
	private Double max;
	
	/**
	 * The bottom limit of the value a number in that property can have. If null, no bottom limit.
	 */
	private Double min;
	
	public RealNumber() {
		this(null,null);
	}
	
	public RealNumber(Double min, Double max) {
		setMin(min);
		setMax(max);
	}

	public Double getMax() {
		return max;
	}

	public void setMax(Double max) {
		this.max = max;
	}

	public Double getMin() {
		return min;
	}

	public void setMin(Double min) {
		this.min = min;
	}

  public String getTypeName() {
    return TYPE_NAME;
  }
  
  public String getDisplayKey() {
  	return TYPE_BUNDLE_KEY;
  }
  
  public String checkValue(Object value) {
		if(!(value instanceof Double))
			return INVALID_TYPE;
		
		Double number = (Double) value;
		
		if(min!=null && number.compareTo(min)<0)
			return INVALID_NUMBER_MIN;
		
		if(max!=null && number.compareTo(max)>0)
			return INVALID_NUMBER_MAX;

		return null;
	}
  
  /**
   * Format : "Number [more than ...|less than ...|between ...]
   */
  public String describe(Locale locale) {
		StringBuffer buffer = new StringBuffer();
		
		buffer.append(ResourceManager.getMessage(TYPE_BUNDLE_KEY, locale));
		if(min!=null) {
			if (max == null) {
				// More than...
				buffer.append(" "+ResourceManager.getMessage(TYPE_BUNDLE_KEY_MORE, locale,
						new String[] { min.toString() }));
			} else {
				// Between...
				buffer.append(" "+ResourceManager.getMessage(TYPE_BUNDLE_KEY_BETWEEN,
						locale, new String[] { min.toString(), max.toString() }));
			}
		} else if(max!=null) {
			// Less than...
			buffer.append(" "+ResourceManager.getMessage(TYPE_BUNDLE_KEY_LESS, locale,
					new String[] { max.toString() }));
		}
		
		return buffer.toString();
	}
  
  public void describeXml(Element elt) {
		if(getMin()!=null)
			elt.addAttribute(MIN_VAL,getMin().toString());
		if(getMax()!=null)
			elt.addAttribute(MAX_VAL,getMax().toString());
	}
  
  public void fillFromXml(Element elt) {
		Attribute attr = elt.getAttribute(MIN_VAL);
		if (attr != null)
			setMin(new Double(attr.getValue()));

		attr = elt.getAttribute(MAX_VAL);
		if (attr != null)
			setMax(new Double(attr.getValue()));
	}

	public Object getValue(String strVal) throws ParseException {
		return new Double(strVal);
	}
}
